package wiiusej.apptest;

import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import wiiusej.MessageDeliver;
import wiiusej.WiiUseApiManager;
import wiiusej.Wiimote;
import wiiusej.apptest.activityTasks.ComClient;
import wiiusej.apptest.activityTasks.Spell;
import wiiusej.connection.ConnectionManager;
import wiiusej.wiiusejevents.GenericEvent;
import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent;

public class AppInitializator implements Runnable{

	private static BlockingQueue<Spell> eneergyToComClient = new LinkedBlockingDeque<Spell>();
	
	private static final int NTHREADS = 200;
	
	private static final ExecutorService exec = 
		Executors.newFixedThreadPool(NTHREADS);
	
	private static HashMap<Integer, Wiimote> wiimotes;
	
	//Logger	
	private static Logger fileLogger;
	
	static private BlockingQueue<HashMap<Integer, BlockingQueue<GenericEvent>>> connectionToAPI;
	static private BlockingQueue<WiiUseApiEvent> apiToConnection;
	static private BlockingQueue<WiiUseApiEvent> postmanToNetListener;
	
	//Components
	static private WiiUseApiManager controller;
	static private ConnectionManager connectionManager;
	static private MessageDeliver messageDeliver;	
	
	private static String[] inputParameters; 
	private static Integer[] simParameters; 
	
	private static int runMode; //normal or network
	private static int simulationLength; //packets per simulation
	private static int timeout; //milliseconds
	
	
	private final static int NORMAL = 0; 
	private final static int NET = 1;
	
	
	
	
	public AppInitializator(int runMode, String[] inputParameters) {
		
		//Log configuration
		PropertyConfigurator.configure("log4j.properties");
		fileLogger = Logger.getLogger("main");
		
		this.inputParameters = inputParameters;
		
		fileLogger.info("Init queues and components");
		
		//Build the communication channels
		initQueues();
		
		//Build the system
		initComponents();
		
	}
	
	public void run() {
		
		
	}
	
	
	private static void initQueues(){		
		
		//COM queue from Connection Manager to WiiuseApiListener
		connectionToAPI = 
			new LinkedBlockingQueue<HashMap<Integer, BlockingQueue<GenericEvent>>>();		
		
		//COM queue from WiiuseApiListener to ConnectionManager - Inform about Disconnection Events
		apiToConnection = new LinkedBlockingDeque<WiiUseApiEvent>();
		
		postmanToNetListener = new LinkedBlockingDeque<WiiUseApiEvent>();
	}
	
	private static void initComponents(){
		
		//API listener
		controller = new WiiUseApiManager();
		
		//Connection controller
		Runnable connection = 
			new ConnectionManager(exec, controller, connectionToAPI, eneergyToComClient, apiToConnection, 
					postmanToNetListener, inputParameters);
		exec.execute(connection);
		
		//Message delivery system
		Runnable postman = 
			new MessageDeliver(connectionToAPI, apiToConnection, controller, postmanToNetListener);		
		exec.execute(postman);
		
		//Runnable gameController = 
			//new SpellGameTask(realTimeToGameController, gameToEnergy, toRumbleQ, fromEnergyToGameQ, wiimote);
		
	}
	
	protected boolean shutdownApp(){
		
		return false;
	}
	
	
	protected static void initComClient(){
		
		Runnable clientServer = 
			new ComClient(eneergyToComClient, wiimotes);
		
		exec.execute(clientServer);
		
	}
	

}
